package com.yun.util.yun.utils.IP;

public class IPAddress {
    private String ip;

    public IPAddress(String ip) {
        this.ip=ip;
    }
    public IPAddress(String ip, int mask) throws Exception {
        this.ip=ip;
        fromString(ip,mask);
    }

    private IPAddress fromString(String ip, int mask) throws Exception {
        if(mask==32)
        {
            this.ip=ip;
        }
        if(mask>32||mask < 0)
        {
            throw new Exception("掩码不合法");
        }
        //ip分四段，每段255，既：2的8次方-1
        String[] ips=ip.split("\\.");
        //取余 用与计算交叉区域的数值
        int lct=mask%8;
        //交叉区前面相同的段
        int ct=(mask-lct)/8;
        if(ct >4)
        {
            throw new Exception("ip格式不合法");
        }
        String ctIp="";
        //补充交叉区前的段
        for(int i = 0;i<ct;i++)
        {
            if(!"".equals(ctIp))
            {
                ctIp+=".";
            }
            ctIp += ips[i];
        }
        int cct =4-ct;
        //余数是0 标识当前ip区域无需计算，直接补满后面的地址即可
        if(lct==0)
        {
            setLastIp(ctIp, cct);
            return this;
        }
        //计算交叉区段IP
        ctIp+="."+setCountCrossOver(ips[ct],lct);
        //如果最后数量多,补充最后IP
        if(cct>1) {
            setLastIp(ctIp, cct - 1);
        }else{
            this.ip=ctIp;
        }
        return this;
    }

    /**
     * 交叉区IP计算
     * @param crossIP 原来交叉区IP
     * @param crossCt 掩码未数
     */
    private String setCountCrossOver(String crossIP,int crossCt) {
        String crosIp2= Integer.toBinaryString(Integer.parseInt(crossIP));
        for(int i = 0;8-crosIp2.length()>0;i++)
        {
            crosIp2="0"+crosIp2;
        }
        String retIp2=crosIp2.substring(0,crossCt);
        for(int i=0;i<8-crossCt;i++)
        {
            retIp2+="1";
        }
        return Integer.parseInt(retIp2, 2)+"";
    }
    /**
     * 补齐后续IP
     * @param sip 前面重复及交叉区IP
     * @param cct 后面剩余的ip段数
     */
    private void setLastIp(String sip,int cct) {
        for(int i=0;i<cct;i++)
        {
            if(!"".equals(sip))
            {
                sip+=".";
            }
            sip+="255";
        }
        this.ip=sip;
    }

    public String getIp(){return this.ip;}

}
